package com.gzucm.Scholarship.controller;

import com.gzucm.Scholarship.dto.ResultDTO;
import com.gzucm.Scholarship.exception.AuthorityException;
import com.gzucm.Scholarship.exception.CurrentException;
import com.gzucm.Scholarship.exception.ImportException;
import com.gzucm.Scholarship.exception.ParameterException;
import com.gzucm.Scholarship.exception.base.DefaultException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 参数错误处理
     *
     * @param request
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = {BindException.class, MethodArgumentNotValidException.class})
    public ResultDTO exceptionHandler(HttpServletRequest request, BindException ex) {
        List<FieldError> errorList = ex.getFieldErrors();
        Map<String, Object> errorMap = new LinkedHashMap<>();
        errorList.forEach(e -> errorMap.put(e.getField(), e.getDefaultMessage()));
        return ResultDTO.failure(HttpStatus.BAD_REQUEST, "参数格式有误", errorMap);
    }

    /**
     * 当前用户服务错误处理
     *
     * @param request
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = CurrentException.class)
    public ResultDTO exceptionHandler(HttpServletRequest request, CurrentException ex) {
        return ResultDTO.failure(HttpStatus.UNAUTHORIZED, ex.getMessage());
    }

    /**
     * 权限检查异常处理
     *
     * @param request
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = AuthorityException.class)
    public ResultDTO exceptionHandler(HttpServletRequest request, AuthorityException ex) {
        return ResultDTO.failure(HttpStatus.FORBIDDEN, ex.getMessage());
    }

    /**
     * 自定义坏请求类型异常处理
     *
     * @param request
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = {ImportException.class, ParameterException.class})
    public ResultDTO exceptionHandler(HttpServletRequest request, DefaultException ex) {
        return ResultDTO.failure(HttpStatus.BAD_REQUEST, ex.getMessage());
    }

    /**
     * 全局异常处理
     *
     * @param request
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResultDTO exceptionHandler(HttpServletRequest request, Exception e) {
        log.error("全局异常拦截:", e);
        return ResultDTO.failure(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
    }

}
